/* 
Scenic Graphics Library
Copyright (C) 2007 Jouni Tulkki

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USApackage scenic;
*/

package scenic;

import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.util.Vector;

import scenic.jni.Renderer;

/**
 * This scene node uses double buffering to reduce rendering time.
 * This class also supports fast scrolling.
 * 
 */
public class SceneDoubleBuffer extends SceneContainer {
	private class Painter implements DoubleBuffer.Painter {

		public void paint(DrawContext context, AffineTransform transform, Rectangle visibleArea) {
			SceneDoubleBuffer.super.draw(context, transform, visibleArea);
		}
	}

	private Vector<DoubleBuffer> buffers = new Vector<DoubleBuffer>();
	private boolean repaintBuffer;
	private boolean repaintNextBuffer;
	private Object renderingInstance;
	private int count;
	
	/**
	 * Constructs an empty SceneDoubleBuffer object.
	 */
	public SceneDoubleBuffer() {
	}
	
	/**
	 * Constructs a SceneDoubleBuffer object with the initial content.
	 
	 * @param content Initial content.
	 */
	public SceneDoubleBuffer(SceneNode content) {
		add(content);
	}
	
	void draw(DrawContext context, AffineTransform transform, Rectangle visibleArea) {
		if(context.renderingInstance != renderingInstance) {
			while(buffers.size() > count) {
				buffers.get(count).free();
				buffers.remove(count);
			}
			renderingInstance = context.renderingInstance; 
			count = 0;
			repaintBuffer = repaintNextBuffer;
			repaintNextBuffer = false;
		}
		if(buffers.size() < count + 1) {
			buffers.add(count, new DoubleBuffer(new Painter()));
		}
		if(repaintBuffer) {
			buffers.get(count).invalidate();
		}
		buffers.get(count).update(context, transform, visibleArea);
		count++;
	}
	
	protected void hide() {
		super.hide();
		for(DoubleBuffer n : buffers) {
			n.free();
		}
		buffers.clear();
		renderingInstance = null;
		count = 0;
	}
	
	public void childChanged(Rectangle area) {
		super.childChanged(area);
		repaintNextBuffer = true;
	}
	
/*	private static boolean equals(Affine2 a, Affine2 b) {
		return a.m00 == b.m00 &&
			a.m01 == b.m01 &&
			a.m10 == b.m10 &&
			a.m11 == b.m11 &&
			a.dx == b.dx &&
			a.dy == b.dy;
	} */
	
}
